﻿using AutoMapper;
using Microsoft.EntityFrameworkCore;
using QMERP.Domain.Dtos;
using QMERP.Domain.Entities;
using QMERP.Domain.Enums;
using QMERP.Infrastructure.CustomException;
using QMERP.Infrastructure.EFCore;
using QMERP.Infrastructure.EFCore.Extensions;
using QMERP.Infrastructure.Extensions;
using QMERP.Infrastructure.Security;
using System.Data;

namespace QMERP.Application.Services
{
    public class EnterStockOrderService : IEnterStockOrderService
    {
        private readonly IMapper _mapper;
        private readonly QMERPDbContext _db;
        private readonly ICurrentUser _currentUser;
        private readonly IStockService _stockSvc;
        private readonly ISerialNumberService _serialNumberSvc;
        public EnterStockOrderService(IMapper mapper, QMERPDbContext db, ICurrentUser currentUser, IStockService stockSvc, ISerialNumberService serialNumberSvc)
        {
            _mapper = mapper;
            _db = db;
            _currentUser = currentUser;
            _stockSvc = stockSvc;
            _serialNumberSvc = serialNumberSvc;
        }
        /// <summary>
        /// 入库单窗体
        /// </summary>
        /// <returns></returns>
        public async Task<PageResponse<EnterStockOrderResponse>> Query(PageRequest<EnterStockOrderRequest> request)
        {
            var response = new PageResponse<EnterStockOrderResponse>();
            var query = Where(request);
            var list = await query.Paging(request.PageIndex, request.PageSize).ToListAsync();
            response.TotalCount = await query.CountAsync();
            response.PageIndex = request.PageIndex;
            response.PageSize = request.PageSize;
            response.List = _mapper.Map<List<EnterStockOrderResponse>>(list);
            return response;
        }
        /// <summary>
        /// 获取id的入库单详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<EnterStockOrderResponse> Detail(long id)
        {
            var model = await _db.EnterStockOrder
                .Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.EnterStockOrderDetail_LensDetails)
                .Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.Warehouse)
                .Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.Lens).AsNoTracking().FindByIdAsync(id);
            var response = _mapper.Map<EnterStockOrderResponse>(model);
            return response;
        }
        /// <summary>
        /// 获取对应业务单类型可入库的订单列表
        /// </summary>
        /// <param name="businessOrderType"></param>
        /// <returns></returns>
        public async Task<List<CanEnterStockOrderResponse>> GetCanEnterStockOrders(string businessOrderType)
        {
            var list = await _db.PurchaseOrder
                    .Include(x => x.PurchaseOrderDetails).ThenInclude(x => x.Warehouse)
                    .Include(x => x.PurchaseOrderDetails).ThenInclude(x => x.Lens).Where(x => x.Status == PurchaseOrderStatusEnum.Receive.ToString() || x.Status == PurchaseOrderStatusEnum.PartialReceived.ToString()).ToListAsync();
            return _mapper.Map<List<CanEnterStockOrderResponse>>(list);
            //if (businessOrderType == EnterStockBusinessOrderTypeEnum.PurchaseOrder.ToString())
            //{
            //    var list = await _db.PurchaseOrder
            //        .Include(x => x.PurchaseOrderDetails).ThenInclude(x => x.Warehouse)
            //        .Include(x => x.PurchaseOrderDetails).ThenInclude(x => x.Lens).Where(x => x.Status == PurchaseOrderStatusEnum.Receive.ToString() || x.Status == PurchaseOrderStatusEnum.PartialReceived.ToString()).ToListAsync();
            //    return _mapper.Map<List<CanEnterStockOrderResponse>>(list);
            //}
            //else
            //{
            //    var list = await _db.TransferOrder
            //        .Include(x => x.TransferOrderDetails).ThenInclude(x => x.InWarehouse)
            //        .Include(x => x.TransferOrderDetails).ThenInclude(x => x.Lens).Where(x => x.Status == TransferOrderStatusEnum.Receive.ToString() || x.Status == TransferOrderStatusEnum.PartialReceived.ToString()).ToListAsync();
            //    return _mapper.Map<List<CanEnterStockOrderResponse>>(list);
            //}
        }
        /// <summary>
        /// 入库单保存
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task<EnterStockOrderResponse> Save(EnterStockOrderSaveRequest request, bool isCheck = false)
        {
            if (request.EnterStockOrderDetails.Count <= 0)
                throw new ApiException("请添加入库镜种信息!");

            var enterStockQty = request.EnterStockOrderDetails.SelectMany(s => s.LensDetails).Sum(s => s.Qty);

            if (enterStockQty <= 0)
                throw new ApiException($"入库总片数不能小于等于0");

            for (int i = 0; i < request.EnterStockOrderDetails.Count; i++)
            {
                string col = $"第{i + 1}行:";
                var detail = request.EnterStockOrderDetails[i];
                var stock = await _db.Stock.GetByWarehouseLens(detail.WarehouseId, detail.LensId);
                if (request.BusinessOrderId == null)
                {
                    if (detail.LensDetails.Count <= 0)
                        throw new ApiException($"{col}请导入XY表!");

                    if (detail.LensDetails.Sum(s => s.Qty) <= 0)
                        throw new ApiException($"{col}XY表总片数为0,请检查!");
                }
                if (!detail.LensDetails.InRange(_mapper.Map<LensResponse>(stock.Lens)))
                    throw new ApiException($"{col}XY表度数超出镜种范围!");

                detail.LensDetails = detail.LensDetails.Where(x => x.Qty > 0).ToList();
            }

            foreach (var detail in request.EnterStockOrderDetails)
                detail.LensDetails = detail.LensDetails.Where(x => x.Qty > 0).ToList();

            EnterStockOrder? model = _mapper.Map<EnterStockOrder>(request);
            if (request.Id != null)
            {
                model = await _db.EnterStockOrder.Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.EnterStockOrderDetail_LensDetails).FindByIdAsync(request.Id.Value);
                if (model == null)
                    throw new ApiException("入库单不存在!");
                model.Remark = request.Remark;
                model.BusinessType = request.BusinessType;
                model.EnterStockOrderDetails = _mapper.Map<List<EnterStockOrderDetail>>(request.EnterStockOrderDetails);
            }
            await ModifyBusinessOrder(model);
            if (request.Id == null)
            {
                string mumber = await _serialNumberSvc.GetSerialNumber(SerialNumberTypeEnum.EnterStockOrder);
                model.Number = mumber;
                model.Status = EnterStockOrderStatusEnum.Pending.ToString();
                await _db.AddAsync(model);
            }
            await _db.SaveChangesAsync();
            if (isCheck)
            {
                model = await _db.EnterStockOrder
                .Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.EnterStockOrderDetail_LensDetails)
                .Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.Warehouse)
                .Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.Lens).FindByIdAsync(model.Id);
                if (model != null)
                {
                    await Check(model);
                    await _db.SaveChangesAsync();
                }
            }
            return _mapper.Map<EnterStockOrderResponse>(model);
        }
        /// <summary>
        /// 入库单审核
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task Check(long[] ids)
        {
            if (ids == null)
                throw new ApiException("id不能为空!");
            var orders = await _db.EnterStockOrder
                .Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.EnterStockOrderDetail_LensDetails).Where(x => ids.Contains(x.Id)).ToListAsync();
            foreach (var order in orders)
            {
                if (order.Status != EnterStockOrderStatusEnum.Pending.ToString())
                    throw new ApiException($"入库单号{order.Number}不能审核!");
                await Check(order);
            }
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 入库单弃审
        /// </summary>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task UnCheck(long[] ids)
        {
            if (ids == null)
                throw new ApiException("id不能为空!");
            var orders = await _db.EnterStockOrder
                .Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.EnterStockOrderDetail_LensDetails).Where(x => ids.Contains(x.Id)).ToListAsync();
            foreach (var order in orders)
            {
                if (order.Status != EnterStockOrderStatusEnum.Checked.ToString())
                    throw new ApiException($"入库单号{order.Number}不能弃审!");
                await UnCheckOrCancel(order);
                order.Status = EnterStockOrderStatusEnum.Pending.ToString();
                order.CheckedBy = null;
                order.CheckedByName = null;
                order.CheckedOn = null;
            }
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 入库单取消
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="isOther"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task Cancel(long[] ids, bool isOther = false)
        {
            if (ids == null)
                throw new ApiException("id不能为空!");

            var orders = await _db.EnterStockOrder
                .Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.EnterStockOrderDetail_LensDetails).Include(x => x.LeaveStockOrder).Where(x => ids.Contains(x.Id)).ToListAsync();
            foreach (var order in orders)
            {
                if (!isOther)
                {
                    if (order.BusinessOrderType == EnterStockBusinessOrderTypeEnum.InventoryOrder.ToString())
                        throw new ApiException($"库存盘点单绑定的入库单号{order.Number}不能取消!");
                }
                if (order.Status != EnterStockOrderStatusEnum.Pending.ToString() && order.Status != EnterStockOrderStatusEnum.Checked.ToString())
                    throw new ApiException($"入库单号{order.Number}不能取消!");
                if (order.LeaveStockOrder != null)
                {
                    order.LeaveStockOrder.Status = LeaveStockOrderStatusEnum.Pending.ToString();
                    order.LeaveStockOrder.CheckedBy = null;
                    order.LeaveStockOrder.CheckedByName = null;
                    order.LeaveStockOrder.CheckedOn = null;
                }
                await UnCheckOrCancel(order);
                order.Status = EnterStockOrderStatusEnum.Canceled.ToString();
            }
            await _db.SaveChangesAsync();
        }
        /// <summary>
        /// 获取入库单主要信息列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<List<EnterStockOrderMainInfoResponse>> GetEnterStockOrderMainInfos(PageRequest<EnterStockOrderRequest> request)
        {
            var orders = await Where(request).ToListAsync();
            var details = orders.SelectMany(s => s.EnterStockOrderDetails).ToList();
            return _mapper.Map<List<EnterStockOrderMainInfoResponse>>(details);
        }
        /// <summary>
        /// 导出缺少收货
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<LensViewResponse> ExportLackReceive(ExportLackReceiveRequest request)
        {
            if (request.businessOrderType == EnterStockBusinessOrderTypeEnum.PurchaseOrder.ToString())
            {
                var detail = await _db.PurchaseOrderDetail.Include(x => x.PurchaseOrder).Include(x => x.PurchaseOrderDetail_LensDetails).Include(x => x.Warehouse).Include(x => x.Lens).FindByIdAsync(request.Id);
                if (detail == null)
                    throw new ApiException("采购单不存在!");
                foreach (var item in detail.PurchaseOrderDetail_LensDetails)
                {
                    item.Qty -= item.EnterStockQty;
                    if (item.Qty <= 0)
                        item.Qty = 0;
                }
                return _mapper.Map<LensViewResponse>(detail);
            }
            else
            {
                var detail = await _db.TransferOrderDetail.Include(x => x.TransferOrder).Include(x => x.InWarehouse).Include(x => x.Lens).FindByIdAsync(request.Id);
                if (detail == null)
                    throw new ApiException("调拨单不存在!");
                foreach (var item in detail.TransferOrderDetail_LensDetails)
                {
                    item.Qty -= item.EnterStockQty;
                    if (item.Qty <= 0)
                        item.Qty = 0;
                }
                return _mapper.Map<LensViewResponse>(detail);
            }
        }
        /// <summary>
        /// 扫描条码入库
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ApiException"></exception>
        public async Task ScanBarCodeEnterStock(ScanBarCodeEnterStockRequest request)
        {
            string sph = "";
            string cyl = "";
            string lensCode = "";
            string degreeType = "-";
            if (!request.BarCode.Contains('-'))
                throw new ApiException("条码格式错误,请检查!");
            if (request.BarCode.Contains('+'))
            {
                string[] strs = request.BarCode.Replace("+", "-").Split('-');
                lensCode = strs[0].Trim();
                sph = "+" + strs[1];
                cyl = strs[2];
                degreeType = "+";
            }
            else
            {
                string[] strs = request.BarCode.Split('-');
                lensCode = strs[0].Trim();
                sph = "-" + strs[1];
                cyl = strs[2];
            }
            var lens = await _db.Lens.Where(x => x.SalesLensCode == lensCode || x.SalesLensCode == lensCode + degreeType).FirstOrDefaultAsync();
            if(lens==null)
                throw new ApiException($"镜种{lensCode}不存在,请检查!");
            var order = new EnterStockOrderSaveRequest()
            { 
                BusinessType = request.BusinessType
            };
            EnterStockOrderDetailSaveRequest detail = new()
            {
                WarehouseId = request.WarehouseId,
                LensId = lens.Id
            };
            string degreesType = "-/-";
            if (sph.ToInt() > 0)
                degreesType = "+/-";
            LensDetailResponse lensDetail = new()
            {
                DegreesType = degreesType,
                SPH = sph.ToInt(),
                CYL = cyl.ToInt(),
                Qty = request.Qty
            };
            detail.LensDetails.Add(lensDetail);
            order.EnterStockOrderDetails.Add(detail);
            await Save(order, true);
        }
        private IQueryable<EnterStockOrder> Where(PageRequest<EnterStockOrderRequest> request)
        {
            IQueryable<EnterStockOrder> query = _db.EnterStockOrder
                .Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.EnterStockOrderDetail_LensDetails)
                .Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.Warehouse)
                .Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.Lens).AsNoTracking();

            if (!request.Query.Number.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.Number.Contains(request.Query.Number!));
            }
            if (!request.Query.BusinessOrderNumber.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.BusinessOrderNumber!.Contains(request.Query.BusinessOrderNumber!));
            }
            if (!request.Query.BusinessOrderType.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.BusinessOrderType == request.Query.BusinessOrderType);
            }
            if (!request.Query.BusinessType.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.BusinessType == request.Query.BusinessType);
            }
            if (!request.Query.CreatedByName.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.CreatedByName.Contains(request.Query.CreatedByName!));
            }
            if (request.Query.CreatedOnStart != null)
            {
                query = query.Where(x => x.CreatedOn >= request.Query.CreatedOnStart.Value.ToStart());
            }
            if (request.Query.CreatedOnEnd != null)
            {
                query = query.Where(x => x.CreatedOn <= request.Query.CreatedOnEnd.Value.ToEnd());
            }
            if (!request.Query.Status.IsNullOrWhiteSpace())
            {
                query = query.Where(x => x.Status == request.Query.Status);
            }
            if (request.Query.WarehouseId != null)
            {
                query = query.Where(x => x.EnterStockOrderDetails.Select(s => s.WarehouseId).Contains(request.Query.WarehouseId.Value));
            }
            if (request.Query.LensId != null)
            {
                query = query.Where(x => x.EnterStockOrderDetails.Select(s => s.LensId).Contains(request.Query.LensId.Value));
            }
            query = query.OrderByDescending(x => x.CreatedOn);
            //if (request.Query.Status == EnterStockOrderStatusEnum.Pending.ToString())
            //{
            //    query = query.OrderByDescending(x => x.CreatedOn);
            //}
            //else if (request.Query.Status == EnterStockOrderStatusEnum.Checked.ToString())
            //{
            //    query = query.OrderByDescending(x => x.CheckedOn);
            //}
            //else
            //{
            //    query = query.OrderByDescending(x => x.UpdatedOn);
            //}
            return query;
        }
        private async Task Check(EnterStockOrder order)
        {
            order.Status = EnterStockOrderStatusEnum.Checked.ToString();
            order.CheckedBy = _currentUser.Id;
            order.CheckedByName = _currentUser.Name;
            order.CheckedOn = DateTime.Now;
            foreach (var esod in order.EnterStockOrderDetails)
            {
                var stock = await _db.Stock.Include(x => x.StockDetails).Where(x => x.WarehouseId == esod.WarehouseId && x.LensId == esod.LensId).FirstOrDefaultAsync();

                if (stock == null)
                    throw new ApiException("入库镜种库存不存在!");

                if (esod.EnterStockOrderDetail_LensDetails.Sum(s => s.Qty) <= 0)
                    continue;

                StockActionLog stockActionLog = new()
                {
                    StockActionType = StockActionTypeEnum.EnterStock.ToString(),
                    BusinessOrderId = order.Id,
                    BusinessOrderNumber = order.Number,
                    BusinessOrderDetailId = esod.Id,
                    BusinessType = order.BusinessType,
                    WarehouseId = esod.WarehouseId,
                    LensId = esod.LensId,
                };

                foreach (var esod_ld in esod.EnterStockOrderDetail_LensDetails)
                {
                    int stockQty = 0;
                    //修改库存片数
                    var stockDetail = stock.StockDetails.Where(x => x.DegreesType == esod_ld.DegreesType && x.SPH == esod_ld.SPH && x.CYL == esod_ld.CYL).FirstOrDefault();
                    if (stockDetail != null)
                    {
                        stockQty = stockDetail.Qty;
                        stockDetail.Qty += esod_ld.Qty;
                    }
                    StockActionLogDetail stockActionLogDetail = new()
                    {
                        DegreesType = esod_ld.DegreesType,
                        SPH = esod_ld.SPH,
                        CYL = esod_ld.CYL,
                        ADD = esod_ld.ADD,
                        Qty = esod_ld.Qty,
                        StockQty = stockQty
                    };
                    stockActionLog.StockActionLogDetails.Add(stockActionLogDetail);
                }
                await _db.AddAsync(stockActionLog);
            }

            if (order.BusinessOrderType == EnterStockBusinessOrderTypeEnum.PurchaseOrder.ToString())
            {
                var po = await _db.PurchaseOrder.Include(x => x.PurchaseOrderDetails).ThenInclude(x => x.PurchaseOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                if (po == null)
                    throw new ApiException($"入库单号{order.Number}对应采购单号{order.BusinessOrderNumber}不存在!");
                foreach (var esod in order.EnterStockOrderDetails)
                {
                    var pod = po.PurchaseOrderDetails.Where(x => x.Id == esod.BusinessOrderDetailId && x.PurchaseOrderDetail_LensDetails.Sum(s => s.Qty) > 0).FirstOrDefault();
                    if (pod != null)
                    {
                        foreach (var esod_ld in esod.EnterStockOrderDetail_LensDetails)
                        {
                            var pod_ld = pod.PurchaseOrderDetail_LensDetails.Where(x => x.DegreesType == esod_ld.DegreesType && x.SPH == esod_ld.SPH && x.CYL == esod_ld.CYL).FirstOrDefault();
                            if (pod_ld != null)
                                pod_ld.EnterStockQty += esod_ld.Qty;
                            else
                                throw new ApiException($"此仓库{esod.Warehouse?.Code}的镜种{esod.Lens?.SalesLensCode}度数SPH:{esod_ld.SPH},CYL{esod_ld.CYL}不用入库!");
                        }
                    }
                }
                var qty = po.PurchaseOrderDetails.SelectMany(s => s.PurchaseOrderDetail_LensDetails).Sum(s => s.Qty - s.EnterStockQty);

                if (qty > 0)
                {
                    po.Status = PurchaseOrderStatusEnum.PartialReceived.ToString();
                }
                else if (qty == 0)
                {
                    po.Status = PurchaseOrderStatusEnum.AllReceived.ToString();
                }
                else
                {
                    po.Status = PurchaseOrderStatusEnum.OverReceived.ToString();
                }
            }
            else if (order.BusinessOrderType == EnterStockBusinessOrderTypeEnum.TransferOrder.ToString())
            {
                var tfo = await _db.TransferOrder.Include(x => x.TransferOrderDetails).ThenInclude(x => x.TransferOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                if (tfo == null)
                    throw new ApiException($"入库单号{order.Number}对应调拨单号{order.BusinessOrderNumber}不存在!");
                foreach (var esod in order.EnterStockOrderDetails)
                {
                    var tfod = tfo.TransferOrderDetails.Where(x => x.Id == esod.BusinessOrderDetailId && x.TransferOrderDetail_LensDetails.Sum(s => s.Qty) > 0).FirstOrDefault();
                    if (tfod != null)
                    {
                        foreach (var esod_ld in esod.EnterStockOrderDetail_LensDetails)
                        {
                            var tfod_ld = tfod.TransferOrderDetail_LensDetails.Where(x => x.DegreesType == esod_ld.DegreesType && x.SPH == esod_ld.SPH && x.CYL == esod_ld.CYL).FirstOrDefault();
                            if (tfod_ld != null)
                            {
                                tfod_ld.EnterStockQty += esod_ld.Qty;
                                if (tfod_ld.EnterStockQty > tfod_ld.Qty)
                                {
                                    throw new ApiException("调拨单不能超出收货片数,请检查!");
                                }
                            }
                            else
                                throw new ApiException($"此仓库{esod.Warehouse?.Code}的镜种{esod.Lens?.SalesLensCode}度数SPH:{esod_ld.SPH},CYL{esod_ld.CYL}不用入库!");
                        }
                    }
                }
                var qty = tfo.TransferOrderDetails.SelectMany(s => s.TransferOrderDetail_LensDetails).Sum(s => s.Qty - s.EnterStockQty);

                if (qty > 0)
                {
                    tfo.Status = TransferOrderStatusEnum.PartialReceived.ToString();
                }
                else if (qty == 0)
                {
                    tfo.Status = TransferOrderStatusEnum.AllReceived.ToString();
                }
                else
                {
                    throw new ApiException("调拨单不能超出收货片数,请检查!");
                }
            }
            else if (order.BusinessOrderType == EnterStockBusinessOrderTypeEnum.TransferLensOrder.ToString())
            {
                var tflo = await _db.TransferLensOrder.Include(x => x.TransferLensOrderDetails).ThenInclude(x => x.TransferLensOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                if (tflo == null)
                    throw new ApiException($"入库单号{order.Number}对应镜种转换单号{order.BusinessOrderNumber}不存在!");
                foreach (var esod in order.EnterStockOrderDetails)
                {
                    var tflod = tflo.TransferLensOrderDetails.Where(x => x.Id == esod.BusinessOrderDetailId && x.TransferLensOrderDetail_LensDetails.Sum(s => s.Qty) > 0).FirstOrDefault();
                    if (tflod != null)
                    {
                        foreach (var esod_ld in esod.EnterStockOrderDetail_LensDetails)
                        {
                            var tfold_ld = tflod.TransferLensOrderDetail_LensDetails.Where(x => x.DegreesType == esod_ld.DegreesType && x.SPH == esod_ld.SPH && x.CYL == esod_ld.CYL).FirstOrDefault();
                            if (tfold_ld != null)
                            {
                                tfold_ld.EnterStockQty += esod_ld.Qty;
                                if (tfold_ld.EnterStockQty > tfold_ld.Qty)
                                {
                                    throw new ApiException("镜种转换单不能超出收货片数,请检查!");
                                }
                            }
                            else
                                throw new ApiException($"此仓库{esod.Warehouse?.Code}的镜种{esod.Lens?.SalesLensCode}度数SPH:{esod_ld.SPH},CYL{esod_ld.CYL}不用入库!");
                        }
                    }
                }
                var qty = tflo.TransferLensOrderDetails.SelectMany(s => s.TransferLensOrderDetail_LensDetails).Sum(s => s.Qty - s.EnterStockQty);

                if (qty != 0)
                {
                    throw new ApiException("镜种转换单不能超出收货片数,请检查!");
                }
                tflo.Status = TransferLensOrderStatusEnum.Finished.ToString();
                tflo.FinishedBy = _currentUser.Id;
                tflo.FinishedByName = _currentUser.Name;
                tflo.FinishedOn = DateTime.Now;
            }
            else if (order.BusinessOrderType == EnterStockBusinessOrderTypeEnum.InventoryOrder.ToString())
            {
                var io = await _db.InventoryOrder.FindByIdAsync(order.BusinessOrderId!.Value);
                if (io == null)
                    throw new ApiException($"入库单号{order.Number}对应库存盘点单号{order.BusinessOrderNumber}不存在!");
                var lso = await _db.LeaveStockOrder.Where(x => x.BusinessOrderId == io.Id && x.BusinessOrderType == LeaveStockBusinessOrderTypeEnum.InventoryOrder.ToString() && x.Status != LeaveStockOrderStatusEnum.Canceled.ToString()).FirstOrDefaultAsync();
                if (lso == null || lso.Status == LeaveStockOrderStatusEnum.Checked.ToString())
                {
                    io.Status = InventoryOrderStatusEnum.Finished.ToString();
                    io.FinishedBy = _currentUser.Id;
                    io.FinishedByName = _currentUser.Name;
                    io.FinishedOn = DateTime.Now;
                }
            }
        }
        private async Task UnCheckOrCancel(EnterStockOrder order)
        {
            if (order.Status == EnterStockOrderStatusEnum.Checked.ToString())
            {
                var stockActionLogs = await _db.StockActionLog.Where(x => x.BusinessOrderId == order.Id && x.StockActionType == StockActionTypeEnum.EnterStock.ToString()).ToListAsync();
                if (stockActionLogs != null)
                {
                    stockActionLogs.ForEach(x => x.IsEnable = false);
                }
                foreach (var esod in order.EnterStockOrderDetails)
                {
                    var stock = await _db.Stock.Include(x => x.StockDetails).Where(x => x.WarehouseId == esod.WarehouseId && x.LensId == esod.LensId).FirstOrDefaultAsync();

                    if (stock == null)
                        throw new ApiException("入库镜种库存不存在!");

                    foreach (var esod_ld in esod.EnterStockOrderDetail_LensDetails)
                    {
                        //修改库存片数
                        var stockDetail = stock.StockDetails.Where(x => x.DegreesType == esod_ld.DegreesType && x.SPH == esod_ld.SPH && x.CYL == esod_ld.CYL).FirstOrDefault();
                        if (stockDetail != null)
                        {
                            stockDetail.Qty -= esod_ld.Qty;
                            if (stockDetail.Qty < 0)
                                throw new ApiException($"入库单号{order.Number}的仓库{esod.Warehouse?.Code}镜种{esod.Lens?.SalesLensCode}SPH:{esod_ld.SPH},CYL:{esod_ld.CYL}库存片数不足扣数!");
                        }
                    }
                }
                if (order.BusinessOrderType == EnterStockBusinessOrderTypeEnum.PurchaseOrder.ToString())
                {
                    var po = await _db.PurchaseOrder.Include(x => x.PurchaseOrderDetails).ThenInclude(x => x.PurchaseOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                    if (po == null)
                        throw new ApiException($"入库单号{order.Number}对应采购单号{order.BusinessOrderNumber}不存在!");
                    foreach (var esod in order.EnterStockOrderDetails)
                    {
                        var pod = po.PurchaseOrderDetails.Where(x => x.Id == esod.BusinessOrderDetailId && x.PurchaseOrderDetail_LensDetails.Sum(s => s.Qty) > 0).FirstOrDefault();
                        if (pod != null)
                        {
                            foreach (var esod_ld in esod.EnterStockOrderDetail_LensDetails)
                            {
                                var pod_ld = pod.PurchaseOrderDetail_LensDetails.Where(x => x.DegreesType == esod_ld.DegreesType && x.SPH == esod_ld.SPH && x.CYL == esod_ld.CYL).FirstOrDefault();
                                if (pod_ld != null)
                                    pod_ld.EnterStockQty -= esod_ld.Qty;
                            }
                        }
                    }
                    var qty = po.PurchaseOrderDetails.SelectMany(s => s.PurchaseOrderDetail_LensDetails).Sum(s => s.Qty - s.EnterStockQty);
                    var totalQty = po.PurchaseOrderDetails.SelectMany(s => s.PurchaseOrderDetail_LensDetails).Sum(s => s.Qty);

                    if (qty - totalQty == 0)
                    {
                        po.Status = PurchaseOrderStatusEnum.Receive.ToString();
                    }
                    else if (qty > 0)
                    {
                        po.Status = PurchaseOrderStatusEnum.PartialReceived.ToString();
                    }
                    else if (qty == 0)
                    {
                        po.Status = PurchaseOrderStatusEnum.AllReceived.ToString();
                    }
                }
                else if (order.BusinessOrderType == EnterStockBusinessOrderTypeEnum.TransferOrder.ToString())
                {
                    var tfo = await _db.TransferOrder.Include(x => x.TransferOrderDetails).ThenInclude(x => x.TransferOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                    if (tfo == null)
                        throw new ApiException($"入库单号{order.Number}对应调拨单号{order.BusinessOrderNumber}不存在!");
                    foreach (var esod in order.EnterStockOrderDetails)
                    {
                        var tfod = tfo.TransferOrderDetails.Where(x => x.Id == esod.BusinessOrderDetailId && x.TransferOrderDetail_LensDetails.Sum(s => s.Qty) > 0).FirstOrDefault();
                        if (tfod != null)
                        {
                            foreach (var esod_ld in esod.EnterStockOrderDetail_LensDetails)
                            {
                                var tfod_ld = tfod.TransferOrderDetail_LensDetails.Where(x => x.DegreesType == esod_ld.DegreesType && x.SPH == esod_ld.SPH && x.CYL == esod_ld.CYL).FirstOrDefault();
                                if (tfod_ld != null)
                                {
                                    tfod_ld.EnterStockQty -= esod_ld.Qty;
                                }
                            }
                        }
                    }
                    var qty = tfo.TransferOrderDetails.SelectMany(s => s.TransferOrderDetail_LensDetails).Sum(s => s.Qty - s.EnterStockQty);
                    var totalQty = tfo.TransferOrderDetails.SelectMany(s => s.TransferOrderDetail_LensDetails).Sum(s => s.Qty);
                    if (qty - totalQty == 0)
                    {
                        tfo.Status = TransferOrderStatusEnum.Receive.ToString();
                    }
                    else if (qty > 0)
                    {
                        tfo.Status = TransferOrderStatusEnum.PartialReceived.ToString();
                    }
                    else if (qty == 0)
                    {
                        tfo.Status = TransferOrderStatusEnum.AllReceived.ToString();
                    }
                }
                else if (order.BusinessOrderType == EnterStockBusinessOrderTypeEnum.TransferLensOrder.ToString())
                {
                    var tflo = await _db.TransferLensOrder.Include(x => x.TransferLensOrderDetails).ThenInclude(x => x.TransferLensOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                    if (tflo == null)
                        throw new ApiException($"入库单号{order.Number}对应镜种转换单号{order.BusinessOrderNumber}不存在!");
                    foreach (var esod in order.EnterStockOrderDetails)
                    {
                        var tflod = tflo.TransferLensOrderDetails.Where(x => x.Id == esod.BusinessOrderDetailId && x.TransferLensOrderDetail_LensDetails.Sum(s => s.Qty) > 0).FirstOrDefault();
                        if (tflod != null)
                        {
                            foreach (var esod_ld in esod.EnterStockOrderDetail_LensDetails)
                            {
                                var tflod_ld = tflod.TransferLensOrderDetail_LensDetails.Where(x => x.DegreesType == esod_ld.DegreesType && x.SPH == esod_ld.SPH && x.CYL == esod_ld.CYL).FirstOrDefault();
                                if (tflod_ld != null)
                                {
                                    tflod_ld.EnterStockQty -= esod_ld.Qty;
                                }
                            }
                        }
                    }
                    //var qty = tflo.TransferLensOrderDetails.SelectMany(s => s.TransferLensOrderDetail_LensDetails).Sum(s => s.Qty - s.EnterStockQty);
                    //var totalQty = tflo.TransferLensOrderDetails.SelectMany(s => s.TransferLensOrderDetail_LensDetails).Sum(s => s.Qty);
                    tflo.Status = TransferLensOrderStatusEnum.Checked.ToString();
                    tflo.FinishedBy = null;
                    tflo.FinishedByName = null;
                    tflo.FinishedOn = null;
                }
                else if (order.BusinessOrderType == EnterStockBusinessOrderTypeEnum.InventoryOrder.ToString())
                {
                    var io = await _db.InventoryOrder.FindByIdAsync(order.BusinessOrderId!.Value);
                    if (io == null)
                        throw new ApiException($"入库单号{order.Number}对应库存盘点单号{order.BusinessOrderNumber}不存在!");
                    if (io.Status == InventoryOrderStatusEnum.Finished.ToString())
                        throw new ApiException($"入库单号{order.Number}对应库存盘点单号{order.BusinessOrderNumber}已完成,不能弃审或取消!");
                }
            } 
        }
        private async Task ModifyBusinessOrder(EnterStockOrder order)
        {
            //var prevOrder = await _db.EnterStockOrder.Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.EnterStockOrderDetail_LensDetails).AsNoTracking().FindByIdAsync(order.Id);
            //取出此业务单已创建未取消的入库单总片数
            var enterStockQty = await _db.EnterStockOrder.Include(x => x.EnterStockOrderDetails).ThenInclude(x => x.EnterStockOrderDetail_LensDetails).AsNoTracking().Where(x => x.Id != order.Id && x.BusinessOrderId == order.BusinessOrderId && x.Status != EnterStockOrderStatusEnum.Canceled.ToString()).SelectMany(s => s.EnterStockOrderDetails).SelectMany(s => s.EnterStockOrderDetail_LensDetails).SumAsync(s => s.Qty);

            if (order.BusinessOrderType == EnterStockBusinessOrderTypeEnum.PurchaseOrder.ToString())
            {
                //var po = await _db.PurchaseOrder.Include(x => x.PurchaseOrderDetails).ThenInclude(x => x.PurchaseOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                //if (po == null)
                //    throw new ApiException("采购单不存在!");

                //var qty = po.PurchaseOrderDetails.SelectMany(s => s.PurchaseOrderDetail_LensDetails).Sum(s => s.Qty);
                //if (qty - enterStockQty < 0)
                //{
                //    throw new ApiException("超出收货片数!");
                //}

                //model.BusinessNumber = order.Number;
                //businessType = EnterStockBusinessTypeEnum.PurchaseIn.ToString();
                //foreach (var esod in order.EnterStockOrderDetails)
                //{
                //    var pod = po.PurchaseOrderDetails.Where(x => x.Id == esod.BusinessOrderDetailId && x.PurchaseOrderDetail_LensDetails.Sum(s => s.Qty) > 0).FirstOrDefault();
                //    if (pod != null)
                //    {
                //        foreach (var esod_ld in esod.EnterStockOrderDetail_LensDetails)
                //        {
                //            var pod_ld = pod.PurchaseOrderDetail_LensDetails.Where(x => x.DegreesType == esod_ld.DegreesType && x.SPH == esod_ld.SPH && x.CYL == esod_ld.CYL).FirstOrDefault();
                //            var enterStockQty = 0;
                //            if (prevOrder != null)
                //            {
                //                var prevLensDetail = prevOrder.EnterStockOrderDetails.Where(x => x.BusinessOrderDetailId == esod.BusinessOrderDetailId).SelectMany(s => s.EnterStockOrderDetail_LensDetails).Where(x => x.DegreesType == esod_ld.DegreesType && x.SPH == esod_ld.SPH && x.CYL == esod_ld.CYL).FirstOrDefault();
                //                if (prevLensDetail != null)
                //                    enterStockQty = prevLensDetail.Qty;
                //            }
                //            if (pod_ld != null)
                //                pod_ld.EnterStockQty= pod_ld.EnterStockQty - enterStockQty + esod_ld.Qty;
                //            else
                //                throw new ApiException($"度数SPH:{esod_ld.SPH},CYL{esod_ld.CYL}不用入库!");
                //        }
                //    }
                //}
                //var qty = po.PurchaseOrderDetails.SelectMany(s => s.PurchaseOrderDetail_LensDetails).Sum(s => s.Qty - s.EnterStockQty);

                //if (qty > 0)
                //{
                //    po.Status = PurchaseOrderStatusEnum.PartialReceived.ToString();
                //}
                //else if (qty == 0)
                //{
                //    po.Status = PurchaseOrderStatusEnum.AllReceived.ToString();
                //}
                //else
                //{
                //    po.Status = PurchaseOrderStatusEnum.OverReceived.ToString();
                //}
            }
            else if (order.BusinessOrderType == EnterStockBusinessOrderTypeEnum.TransferOrder.ToString())
            {
                var tfo = await _db.TransferOrder.Include(x => x.TransferOrderDetails).ThenInclude(x => x.TransferOrderDetail_LensDetails).FindByIdAsync(order.BusinessOrderId!.Value);
                if (tfo == null)
                    throw new ApiException("调拨单不存在!");

                var qty = tfo.TransferOrderDetails.SelectMany(s => s.TransferOrderDetail_LensDetails).Sum(s => s.Qty);
                if (qty - enterStockQty < 0)
                {
                    throw new ApiException("调拨单不能超出收货片数,请检查!");
                }

                //businessType = EnterStockBusinessTypeEnum.TransferIn.ToString();
                //foreach (var esod in order.EnterStockOrderDetails)
                //{
                //    var tfod = tfo.TransferOrderDetails.Where(x => x.Id == esod.BusinessOrderDetailId && x.TransferOrderDetail_LensDetails.Sum(s => s.Qty) > 0).FirstOrDefault();
                //    if (tfod != null)
                //    {
                //        foreach (var esod_ld in esod.EnterStockOrderDetail_LensDetails)
                //        {
                //            var tfod_ld = tfod.TransferOrderDetail_LensDetails.Where(x => x.DegreesType == esod_ld.DegreesType && x.SPH == esod_ld.SPH && x.CYL == esod_ld.CYL).FirstOrDefault();
                //            var enterStockQty = 0;
                //            if (prevOrder != null)
                //            {
                //                var prevLensDetail = prevOrder.EnterStockOrderDetails.Where(x => x.BusinessOrderDetailId == esod.BusinessOrderDetailId).SelectMany(s => s.EnterStockOrderDetail_LensDetails).Where(x => x.DegreesType == esod_ld.DegreesType && x.SPH == esod_ld.SPH && x.CYL == esod_ld.CYL).FirstOrDefault();
                //                if (prevLensDetail != null)
                //                    enterStockQty = prevLensDetail.Qty;
                //            }
                //            if (tfod_ld != null)
                //            {
                //                tfod_ld.EnterStockQty = tfod_ld.EnterStockQty - enterStockQty + esod_ld.Qty;
                //                if (tfod_ld.EnterStockQty > tfod_ld.Qty)
                //                {
                //                    throw new ApiException("调拨单不能超出收货片数,请检查!");
                //                }
                //            }
                //            else
                //                throw new ApiException($"度数SPH:{esod_ld.SPH},CYL{esod_ld.CYL}不用入库!");
                //        }
                //    }
                //    var qty = tfo.TransferOrderDetails.SelectMany(s => s.TransferOrderDetail_LensDetails).Sum(s => s.Qty - s.EnterStockQty);

                //    if (qty > 0)
                //    {
                //        tfo.Status = TransferOrderStatusEnum.PartialReceived.ToString();
                //    }
                //    else if (qty == 0)
                //    {
                //        tfo.Status = TransferOrderStatusEnum.AllReceived.ToString();
                //    }
                //    else
                //    {
                //        throw new ApiException("调拨单不能超出收货片数,请检查!");
                //    }
                //}
            }
        }
    }
}
